"""
AI Agent Pro - FastAPI 主应用入口
"""

import asyncio
import logging
import time
from contextlib import asynccontextmanager
from typing import Any, Dict

import uvicorn
from fastapi import FastAPI, Request, Response, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.responses import JSONResponse
from prometheus_client import Counter, Histogram, generate_latest
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.errors import RateLimitExceeded
from slowapi.util import get_remote_address
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import PlainTextResponse

from app.core.config import get_settings
from app.core.database import init_db
from app.core.logging import setup_logging
from app.api.v1 import api_router
from app.core.exceptions import setup_exception_handlers

# 设置日志
setup_logging()
logger = logging.getLogger(__name__)

# 配置设置
settings = get_settings()

# Prometheus 指标
request_count = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint', 'status'])
request_duration = Histogram('http_request_duration_seconds', 'HTTP request duration')
agent_requests = Counter('agent_requests_total', 'Total agent requests', ['agent_type'])


class PrometheusMiddleware(BaseHTTPMiddleware):
    """Prometheus 指标收集中间件"""
    
    async def dispatch(self, request: Request, call_next):
        start_time = time.time()
        
        response = await call_next(request)
        
        # 记录指标
        method = request.method
        endpoint = request.url.path
        status_code = response.status_code
        
        request_count.labels(method=method, endpoint=endpoint, status=status_code).inc()
        request_duration.observe(time.time() - start_time)
        
        return response


class SecurityMiddleware(BaseHTTPMiddleware):
    """安全中间件 - 添加安全头"""
    
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        
        # 添加安全头
        response.headers["X-Content-Type-Options"] = "nosniff"
        response.headers["X-Frame-Options"] = "DENY"
        response.headers["X-XSS-Protection"] = "1; mode=block"
        response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
        response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
        
        return response


# 限流器
limiter = Limiter(key_func=get_remote_address, default_limits=["100/minute"])


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时执行
    logger.info("🚀 AI Agent Pro 启动中...")
    
    # 初始化数据库
    await init_db()
    logger.info("✅ 数据库初始化完成")
    
    # 初始化向量数据库
    # await init_vector_db()
    logger.info("✅ 向量数据库连接成功")
    
    # 预热AI模型
    # await warm_up_models()
    logger.info("✅ AI模型预热完成")
    
    logger.info("🎉 AI Agent Pro 启动成功！")
    
    yield
    
    # 关闭时执行
    logger.info("🛑 AI Agent Pro 正在关闭...")
    # 清理资源
    logger.info("✅ 资源清理完成")


# 创建 FastAPI 应用
app = FastAPI(
    title="AI Agent Pro API",
    description="专业智能体开发平台 - RESTful API",
    version="1.0.0",
    docs_url="/docs" if settings.environment != "production" else None,
    redoc_url="/redoc" if settings.environment != "production" else None,
    lifespan=lifespan,
)

# 设置限流器
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

# 添加中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.add_middleware(GZipMiddleware, minimum_size=1000)
app.add_middleware(PrometheusMiddleware)
app.add_middleware(SecurityMiddleware)

# 设置异常处理器
setup_exception_handlers(app)

# 注册路由
app.include_router(api_router, prefix="/api/v1")


# 健康检查端点
@app.get("/health", tags=["监控"])
async def health_check():
    """健康检查端点"""
    return {
        "status": "healthy",
        "timestamp": time.time(),
        "version": "1.0.0",
        "environment": settings.environment,
    }


@app.get("/health/detailed", tags=["监控"])
async def detailed_health_check():
    """详细健康检查"""
    checks = {}
    
    # 检查数据库连接
    try:
        # 这里应该检查数据库连接
        checks["database"] = {"status": "healthy", "response_time": "< 10ms"}
    except Exception as e:
        checks["database"] = {"status": "unhealthy", "error": str(e)}
    
    # 检查 Redis 连接
    try:
        # 这里应该检查 Redis 连接
        checks["redis"] = {"status": "healthy", "response_time": "< 5ms"}
    except Exception as e:
        checks["redis"] = {"status": "unhealthy", "error": str(e)}
    
    # 检查 AI 服务
    try:
        # 这里应该检查 AI 服务连接
        checks["ai_services"] = {"status": "healthy", "models": ["gpt-4", "claude-3"]}
    except Exception as e:
        checks["ai_services"] = {"status": "unhealthy", "error": str(e)}
    
    # 检查向量数据库
    try:
        checks["vector_db"] = {"status": "healthy", "collections": 5}
    except Exception as e:
        checks["vector_db"] = {"status": "unhealthy", "error": str(e)}
    
    # 计算整体状态
    overall_status = "healthy" if all(
        check["status"] == "healthy" for check in checks.values()
    ) else "unhealthy"
    
    return {
        "status": overall_status,
        "timestamp": time.time(),
        "checks": checks,
        "version": "1.0.0",
    }


@app.get("/metrics", tags=["监控"])
async def prometheus_metrics():
    """Prometheus 指标端点"""
    return PlainTextResponse(generate_latest())


@app.get("/", tags=["根路径"])
async def root():
    """API 根路径"""
    return {
        "message": "🤖 欢迎使用 AI Agent Pro API!",
        "version": "1.0.0",
        "docs": "/docs",
        "health": "/health",
        "metrics": "/metrics",
    }


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    """添加请求处理时间头"""
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response


@app.exception_handler(500)
async def internal_server_error_handler(request: Request, exc: Exception):
    """内部服务器错误处理"""
    logger.error(f"Internal server error: {exc}", exc_info=True)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "error": "内部服务器错误",
            "message": "服务暂时不可用，请稍后重试",
            "timestamp": time.time(),
        }
    )


# WebSocket 连接管理
class ConnectionManager:
    """WebSocket 连接管理器"""
    
    def __init__(self):
        self.active_connections: Dict[str, Any] = {}
    
    async def connect(self, websocket, client_id: str):
        await websocket.accept()
        self.active_connections[client_id] = websocket
        logger.info(f"客户端 {client_id} 已连接")
    
    def disconnect(self, client_id: str):
        if client_id in self.active_connections:
            del self.active_connections[client_id]
            logger.info(f"客户端 {client_id} 已断开连接")
    
    async def send_personal_message(self, message: str, client_id: str):
        if client_id in self.active_connections:
            websocket = self.active_connections[client_id]
            await websocket.send_text(message)
    
    async def broadcast(self, message: str):
        for connection in self.active_connections.values():
            await connection.send_text(message)


manager = ConnectionManager()


if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=settings.backend_port,
        reload=settings.debug,
        log_level=settings.log_level.lower(),
        access_log=True,
    )